package com.jinmdz.fmis.api.wrapper;

import com.jinmdz.fmis.api.base.BaseService;
import com.jinmdz.fmis.common.util.DataUtil;
import com.jinmdz.fmis.core.exception.ActionException;
import com.jinmdz.fmis.core.license.CertificateExtraModel;
import com.jinmdz.fmis.core.license.CertificateKeyStoreParam;
import com.jinmdz.fmis.core.license.CertificateLicenseManager;
import com.jinmdz.fmis.core.util.LogUtil;
import de.schlichtherle.license.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.prefs.Preferences;

/**
 * License校验封装处理类
 * (源自网络)
 *
 * @author LiCongLu
 * @date 2020-01-08 15:45
 */
@Component
public class LicenseWrapper extends BaseService {

    /**
     * 证书subject
     */
    @Value("${license.subject:''}")
    private String subject;

    /**
     * 公钥别称
     */
    @Value("${license.public-alias:''}")
    private String publicAlias;

    /**
     * 访问公钥库的密码
     */
    @Value("${license.store-pass:''}")
    private String storePass;

    /**
     * 证书生成路径
     */
    @Value("${license.license-path:''}")
    private String licensePath;

    /**
     * 密钥库存储路径
     */
    @Value("${license.public-key-store-path:''}")
    private String publicKeyStorePath;

    /**
     * LicenseManager
     */
    private CertificateLicenseManager licenseManager;

    /**
     * 标识证书是否安装成功
     */
    private boolean installSuccess;

    /**
     * Bean初始化函数
     *
     * @param
     * @return
     * @author LiCongLu
     * @date 2020-01-09 08:34
     */
    @PostConstruct
    public void initMethod() throws ActionException {
        // 验证配置不为空
        if (DataUtil.invalid(subject, publicAlias, storePass, licensePath, publicKeyStorePath)) {
            LogUtil.info("----> 许可证书未能安装，配置为空");
            // throw new ActionException("许可证书未能安装，配置为空");
            return;
        }

        // 验证存在证书文件
        File licFile = new File(licensePath);
        File keyStoreFile = new File(publicKeyStorePath);
        if (!licFile.exists() || !keyStoreFile.exists()) {
            LogUtil.info("----> 许可证书未能安装，配置证书文件不存在");
            // throw new ActionException("许可证书未能安装，配置证书文件不存在");
            return;
        }

        // 安装识别许可证号
        installLicense();
    }

    /**
     * Bean销毁函数
     *
     * @param
     * @return
     * @author LiCongLu
     * @date 2020-01-09 08:34
     */
    @PreDestroy
    public void destroyMethod() {
        uninstallLicense();
    }

    /**
     * 安装License证书，读取证书相关的信息
     *
     * @param
     * @return
     * @author LiCongLu
     * @date 2020-01-08 15:48
     */
    public void installLicense() throws ActionException {
        try {
            Preferences preferences = Preferences.userNodeForPackage(LicenseWrapper.class);
            CipherParam cipherParam = new DefaultCipherParam(storePass);
            KeyStoreParam publicStoreParam = new CertificateKeyStoreParam(LicenseWrapper.class,
                    publicKeyStorePath,
                    publicAlias,
                    storePass,
                    null);
            LicenseParam licenseParam = new DefaultLicenseParam(subject, preferences, publicStoreParam, cipherParam);
            // 创建验证管理并传递日期参数
            licenseManager = new CertificateLicenseManager(licenseParam, new CertificateLicenseManager.OnNowDateListener() {
                @Override
                public Date onNowDate() {
                    // 按照数据库的参数
                    return nowDate();
                }
            });
            licenseManager.uninstall();
            LicenseContent licenseContent = licenseManager.install(new File(licensePath));
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            installSuccess = true;
            LogUtil.info(" --> 许可证书安装成功");
            LogUtil.info(MessageFormat.format(" --> 许可证书有效期：{0} - {1}", format.format(licenseContent.getNotBefore()), format.format(licenseContent.getNotAfter())));
        } catch (Exception e) {
            installSuccess = false;
            LogUtil.info(" --> 许可证书安装失败，原因：" + e.getMessage());
            // 当抛出异常时，可阻止接口系统启动
            // throw new ActionException("许可证书安装失败");
        }
    }

    /**
     * 卸载证书
     *
     * @param
     * @return
     * @author LiCongLu
     * @date 2020-01-08 15:48
     */
    public void uninstallLicense() {
        if (installSuccess) {
            try {
                licenseManager.uninstall();
            } catch (Exception e) {
            }
        }
    }

    /**
     * 校验License证书
     *
     * @param
     * @return
     * @author LiCongLu
     * @date 2020-01-08 15:48
     */
    public boolean verifyLicense() {
        if (installSuccess) {
            try {
                LicenseContent licenseContent = licenseManager.verify();
                return true;
            } catch (Exception e) {
                LogUtil.line("许可证失效:" + e.getMessage());
            }
        }
        return false;
    }

    /**
     * 获取许可证绑定的扩展加密狗信息
     *
     * @param
     * @return
     * @author LiCongLu
     * @date 2020-04-16 14:00
     */
    public CertificateExtraModel getExtraModel() {
        if (licenseManager != null) {
            return licenseManager.getExtraModel();
        }
        return null;
    }

    /**
     * 返回信息列表
     *
     * @param
     * @return
     * @author LiCongLu
     * @date 2020-04-17 13:57
     */
    public String getMessage() {
        if (licenseManager != null) {
            return licenseManager.getMessage();
        }
        return null;
    }
}